Skip Headers

Oracle® XML DB Developer's Guide 10g Release 2 (10.2) Part Number B14259-02 |
Home | Book List | Contents | Index | Master Index | Feedback

Previous | Next
| View PDF

# 27 Writing Oracle XML DB Applications in Java

This chapter describes how to write Oracle XML DB applications in Java. It includes design guidelines for writing Java applications including servlets, and how to configure the Oracle XML DB servlets.

This chapter contains these topics:

- Overview of Oracle XML DB Java Applications

- Design Guidelines: Java Inside or Outside the Database?

- Writing Oracle XML DB HTTP Servlets in Java

- Configuring Oracle XML DB Servlets

- HTTP Request Processing for Oracle XML DB Servlets

- Session Pool and Oracle XML DB Servlets

- Native XML Stream Support

- Oracle XML DB Servlet APIs

- Oracle XML DB Servlet Example

## Overview of Oracle XML DB Java Applications

Oracle XML DB provides two main architectures for the Java programmer:

- In the database using the Java Virtual Machine (VM)

- In a client or application server, using the thick JDBC driver. An application server is a server designed to host applications and their environments, permitting server applications to run. A typical example is Oracle Application Server, which is able to host Java, C, C++, and PL/SQL applications in cases where a remote client controls the interface. See also Oracle Application Server. The Oracle Application Server, that integrates all the core services and features required for building, deploying, and managing high-performance, n-tier, transaction-oriented Web applications within an open standards framework.

Because Java in the database runs in the context of the database server process, the methods of deploying your Java code are restricted to one of the following ways:

- You can run Java code as a stored procedure invoked from SQL or PL/SQL or

- You can run a Java servlet.

Stored procedures are easier to integrate with SQL and PL/SQL code, and require using Oracle Net Services as the protocol to access Oracle Database.

Servlets work better as the top-level entry point into Oracle Database, and require using HTTP(S) as the protocol to access Oracle Database.

### Which Oracle XML DB APIs Are Available Inside and Outside the Database?

All Oracle XML DB application program interfaces (APIs) are available to applications running both in the server and outside the database, including:

- JDBC support for `XMLType`

- `XMLType` class

- Java DOM implementation

## Design Guidelines: Java Inside or Outside the Database?

When choosing an architecture for writing Java Oracle XML DB applications, consider the following guidelines:

### HTTP(S): Accessing Java Servlets or Directly Accessing XMLType Resources

If the downstream client wants to deal with XML in its textual representation, then using HTTP(S) to either access the Java servlets or directly access `XMLType` resources, will perform the best, especially if the XML node tree is not being manipulated much by the Java program.

The Java implementation in the server can natively move data from the database to the network without converting character data through UCS-2 Unicode (which is required by Java strings), and in many cases copies data directly from the database buffer cache to the HTTP(S) connection. There is no requirement to convert data from the buffer cache into the SQL serialization format used by Oracle Net Services, move it to the JDBC client, and then convert to XML. The load-on-demand and LRU cache for `XMLType` are most effective inside the database server.

### Accessing Many XMLType Object Elements: Use JDBC XMLType Support

If the downstream client is an application that will programmatically access many or most of the elements of an XMLType object using Java, then using JDBC `XMLType` support will probably perform the best. It is often easier to debug Java programs outside of the database server, as well.

### Use the Servlets to Manipulate and Write Out Data Quickly as XML

Oracle XML DB servlets are intended for writing HTTP stored procedures in Java that can be accessed using HTTP(S). They are not intended as a platform for developing an entire Internet application. In that case, the application servlet should be deployed in Oracle Application Server application server and access data in the database either using JDBC, or by using the `java.net.*` or similar APIs to get XML data through HTTP(S).

They are best used for applications that want to get into the database, manipulate the data, and write it out quickly as XML, not to format HTML pages for end-users.

## Writing Oracle XML DB HTTP Servlets in Java

Oracle XML DB provides a protocol server that supports FTP, HTTP 1.1, WebDAV, and Java Servlets. The support for Java Servlets in this release is not complete, and provides a subset designed for easy migration to full compliance in a following release. Currently, Oracle XML DB supports Java Servlet version 2.2, with the following exceptions:

- The servlet WAR file (`web.xml`) is not supported in its entirety. Some `web.xml` configuration parameters must be handled manually. For example, creating roles must be done using the `SQL CREATE ROLE` command.

- `RequestDispatcher` and associated methods are not supported.

- `HTTPServletRequest.getCookies()` method is not supported.

- Only one `ServletContext` (and one web-app) is currently supported.

- Stateful servlets (and thus the `HttpSession` class methods) are not supported. Servlets must maintain state in the database itself.

## Configuring Oracle XML DB Servlets

Oracle XML DB servlets are configured using the `/xdbconfig.xml` file in Oracle XML DB Repository. Many of the XML elements in this file are the same as those defined by the Java Servlet 2.2 specification portion of Java 2 Enterprise Edition (J2EE), and have the same semantics. Table 27-1 lists the XML elements defined for the servlet deployment descriptor by the Java Servlet specification, along with extension elements supported by Oracle XML DB.

Table 27-1 XML Elements Defined for Servlet Deployment Descriptors

XML Element Name | Defined By | Supported? | Description | Comment
--- | --- | --- | --- | ---
`auth-method` | Java | no | Specifies an HTTP authentication method required for access | --
`charset` | Oracle | yes | Specifies an IANA character set name | For example: ISO8859, UTF-8
`charset-mapping` | Oracle | yes | Specifies a mapping between a filename extension and a charset | --
`context-param` | Java | no | Specifies a parameter for a web application | Not yet supported
`description` | Java | yes | A string for describing a servlet or Web application | Supported for servlets
`display-name` | Java | yes | A string to display with a servlet or web app | Supported for servlets
`distributable` | Java | no | Indicates whether or not this servlet can function if all instances are not running in the same Java virtual machine | All servlets running in Oracle Database MUST be distributable.
`errnum` | Oracle | yes | Oracle error number | See Oracle Database Error Messages
`error-code` | Java | yes | HTTP(S) error code | Defined by RFC 2616
`error-page` | Java | yes | Defines a URL to redirect to if an error is encountered. | Can be specified through an HTTP(S) error, an uncaught Java exception, or through an uncaught Oracle error message
`exception-type` | Java | yes | Classname of a Java exception mapped to an error page | --
`extension` | Java | yes | A filename extension used to associate with MIME types, character sets, and so on. | --
`facility` | Oracle | yes | Oracle facility code for mapping error pages | For example: ORA, PLS, and so on.
`form-error-page` | Java | no | Error page for form login attempts | Not yet supported
`form-login-config` | Java | no | Config spec for form-based login | Not yet supported
`form-login-page` | Java | no | URL for the form-based login page | Not yet supported
`icon` | Java | Yes | URL of icon to associate with a servlet | Supported for servlets
`init-param` | Java | Yes | Initialization parameter for a servlet | --
`jsp-file` | Java | No | Java Server Page file to use for a servlet | Not supported
`lang` | Oracle | Yes | IANA language name | For example: en-US
`lang-mapping` | Oracle | Yes | Specifies a mapping between a filename extension and language content | --
`large-icon` | Java | Yes | Large sized icon for icon display | --
`load-on-startup` | Java | Yes | Specifies if a servlet is to be loaded on startup | --
`location` | Java | Yes | Specifies the URL for an error page | Can be a local path name or HTTP(S) URL
`login-config` | Java | No | Specifies a method for authentication | Not yet supported
`mime-mapping` | Java | Yes | Specifies a mapping between filename extension and the MIME type of the content | --
`mime-type` | Java | Yes | MIME type name for resource content | For example: text/xml or application/octet-stream
`OracleError` | Oracle | Yes | Specifies an Oracle error to associate with an error page | --
`param-name` | Java | Yes | Name of a parameter for a Servlet or `ServletContext` | Supported for servlets
`param-value` | Java | Yes | Value of a parameter | --
`realm-name` | Java | No | HTTP(S) realm used for authentication | Not yet supported
`role-link` | Java | Yes | Specifies a role a particular user must have in order to access a servlet | Refers to a database role name. Make sure to capitalize by default!
`role-name` | Java | Yes | A servlet name for a role | Just another name to call the database role. Used by the Servlet APIs
`security-role` | Java | No | Defines a role for a servlet to use | Not supported. You must manually create roles using the SQL `CREATE ROLE`
`security-role-ref` | Java | Yes | A reference between a servlet and a role | --
`servlet` | Java | Yes | Configuration information for a servlet | --
`servlet-class` | Java | Yes | Specifies the classname for the Java servlet | --
`servlet-language` | Oracle | Yes | Specifies the programming language in which the servlet is written. | Either Java, C, or PL/SQL. Currently, only Java is supported for customer-defined servlets.
`servlet-mapping` | Java | Yes | Specifies a filename pattern with which to associate the servlet | All of the mappings defined by Java are supported
`servlet-name` | Java | Yes | String name for a servlet | Used by servlet APIs
`servlet-schema` | Oracle | Yes | The Oracle Schema in which the Java class is loaded. If not specified, then the schema is searched using the default resolver specification. | If this is not specified, then the servlet must be loaded into the `SYS` schema to ensure that everyone can access it, or the default Java class resolver must be altered. Note that the servlet schema is capitalized unless the value is enclosed in double-quotes.
`session-config` | Java | No | Configuration information for an `HTTPSession` | `HTTPSession` is not supported
`session-timeout` | Java | No | Timeout for an HTTP(S) session | `HTTPSession` is not supported
`small-icon` | Java | Yes | Small icon to associate with a servlet | --
`taglib` | Java | No | JSP tag library | JSPs currently not supported
`taglib-uri` | Java | No | URI for JSP tag library description file relative to the web.xml file | JSPs currently not supported
`taglib-location` | Java | No | Path name relative to the root of the web application where the tag library is stored | JSPs currently not supported
`url-pattern` | Java | Yes | URL pattern to associate with a servlet | See Section 10 of Java Servlet 2.2 spec
`web-app` | Java | No | Configuration for a web application | Only one web application is currently supported
`welcome-file` | Java | Yes | Specifies a welcome-file name | --
`welcome-file-list` | Java | Yes | Defines a list of files to display when a folder is referenced through an HTTP `GET` request | Example: `index.html`

Note: The following parameters defined for the `web.xml` file by Java are usable only by J2EE-compliant Enterprise Java Bean containers, and are not required for Java Servlet Containers that do not support a full J2EE environment: env-entry, env-entry-name, env-entry-value, env-entry-type, ejb-ref, ejb-ref-type, home, remote, ejb-link, resource-ref, res-ref-name, res-type, res-auth The following elements are used to define access control for resources: security-constraint, web-resource-collection, web-resource-name, http-method, user-data-constraint, transport-guarantee, auth-constrain. Oracle XML DB provides this functionality through access control lists (ACLs). An ACL is a list of access control entries that determines which principals have access to a given resource or resources. A future release will support using a `web.xml` file to generate ACLs.

See Also: Chapter 28, "Administering Oracle XML DB" for more information about configuring the `/xdbconfig.xml` file

## HTTP Request Processing for Oracle XML DB Servlets

Oracle XML DB handles an HTTP request using the following steps:

1. If a connection has not yet been established, then Oracle Listener hands the connection to a shared server dispatcher.

2. When a new HTTP request arrives, the dispatcher wakes up a shared server.

3. The HTTP headers are parsed into appropriate structures.

4. The shared server attempts to allocate a database session from the Oracle XML DB session pool, if available, but otherwise will create a new session.

5. A new database call is started, as well as a new database transaction.

6. If HTTP(S) has included authentication headers, then the session will be authenticated as that database user (just as if the user logged into SQL*Plus). If no authentication information is included, and the request is `GET` or `HEAD`, then Oracle XML DB attempts to authenticate the session as the `ANONYMOUS` user. If that database user account is locked, then no unauthenticated access is allowed.

7. The URL in the HTTP request is matched against the servlets in the `xdbconfig.xml` file, as specified by the Java Servlet 2.2 specification.

8. The Oracle XML DB Servlet Container is invoked in the Java VM inside Oracle. If the specified servlet has not been initialized yet, then the servlet is initialized.

9. The Servlet reads input from the `ServletInputStream`, and writes output to the `ServletOutputStream`, and returns from the `service()` method.

10. If no uncaught Oracle error occurred, then the session is put back into the session pool.

    See Also: Chapter 25, "FTP, HTTP(S), and WebDAV Access to Repository Data"

## Session Pool and Oracle XML DB Servlets

Oracle Database keeps one Java VM for each database session. This means that a session reused from the session pool will have any state in the Java VM (Java static variables) from the last time the session was used.

This can be useful in caching Java state that is not user-specific, such as metadata, but Do not store secure user data in java static memory. This could turn into a security hole inadvertently introduced by your application if you are not careful.

## Native XML Stream Support

The `DOM` Node class has an Oracle-specific method called `write()`, that takes the following arguments, returning void:

- `java.io.OutputStream` stream: A Java stream to write the XML text to

- String `charEncoding`: The character encoding to write the XML text in. If `NULL`, then the database character set is used

- `Short` `indent` The number of characters to indent nested XML elements

This method has a shortcut implementation if the stream provided is the `ServletOutputStream` provided inside the database. The contents of the Node are written in XML in native code directly to the output socket. This bypasses any conversions into and out of Java objects or Unicode (required for Java strings) and provides very high performance.

## Oracle XML DB Servlet APIs

The APIs supported by Oracle XML DB servlets are defined by the Java Servlet 2.2 specification, the `Javadoc` for which is available, as of the time of writing this, online at: `http://java.sun.com/products/servlet/2.2/javadoc/index.html`

Table 27-2 lists Java Servlet 2.2 methods that are not implemented. They result in runtime exceptions.

Table 27-2 Java 2.2 Methods That Are Not Implemented

Interface | Methods
--- | ---
    HttpServletRequest
| `getSession(), isRequestedSessionIdValid()`
    HttpSession
| all
    HttpSessionBindingListener
| all

## Oracle XML DB Servlet Example

The following is a simple servlet example that reads a parameter specified in a URL as a path name, and writes out the content of that XML document to the output stream.

Example 27-1 Writing an Oracle XML DB Servlet

The servlet code looks like this:

    /* test.java */
    import javax.servlet.http.*;
    import javax.servlet.*;
    import java.util.*;
    import java.io.*;
    import javax.naming.*;
    import oracle.xdb.dom.*;

    public class test extends HttpServlet
    {
      protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
      {
        OutputStream os = resp.getOutputStream();
        Hashtable    env = new Hashtable();
        XDBDocument  xt;

        try
        {
          env.put(Context.INITIAL_CONTEXT_FACTORY,
                  "oracle.xdb.spi.XDBContextFactory");
          Context ctx = new InitialContext(env);
          String [] docarr  = req.getParameterValues("doc");
          String doc;
          if (docarr == null || docarr.length == 0)
            doc = "/foo.txt";
          else
            doc = docarr[0];
          xt = (XDBDocument)ctx.lookup(doc);
          resp.setContentType("text/xml");
          xt.write(os, "ISO8859", (short)2);
        }
        catch (javax.naming.NamingException e)
        {
          resp.sendError(404, "Got exception: " + e);
        }
        finally
        {
          os.close();
        }
      }
    }

### Installing the Oracle XML DB Example Servlet

To install this servlet, compile it, and load it into Oracle Database using commands such as:

    % loadjava –grant public –u scott/tiger –r test.class

### Configuring the Oracle XML DB Example Servlet

To configure Oracle XML DB servlet, update the `/xdbconfig.xml` file by inserting the following XML element tree in the `servlet-list` element:

    <servlet>
      <servlet-name>TestServlet</servlet-name>
      <servlet-language>Java</servlet-language>
      <display-name>Oracle XML DB Test Servlet</display-name>
      <servlet-class>test</servlet-class>
      <servlet-schema>scott</servlet-schema>
    </servlet>

and update the `/xdbconfig.xml` file by inserting the following XML element tree in the `<servlet-mappings>` element:

    <servlet-mapping>
      <servlet-pattern>/testserv</servlet-pattern>
      <servlet-name>TestServlet</servlet-name>
    </servlet-mapping>

You can edit the `/xdbconfig.xml` file with any WebDAV-capable text editor, or by using SQL function `updateXML`.

Note: You cannot delete file `/xdbconfig.xml`, even `as SYS`.

### Testing the Example Servlet

To test the example servlet, load an arbitrary XML file at `/foo.xml`, and type the following URL into your browser, replacing the `hostname` and port number as appropriate:

    http://hostname:8080/testserv?doc=/foo.xml